现在来看看如何编写自定义选择器。除了本章的例子，第12章还有一些例子。内置的设备选择器旨在快速启动代码并运行。真正的程序通常需要对设备进行选择，例如:从系统中可用的一组GPU类型中选择所需的GPU。设备选择机制很容易扩展为复杂的逻辑，因此可以编写代码来选择设备。\par

\hspace*{\fill} \par %插入空行
\textbf{device\_selector基类}

所有的设备选择器都从device\_selector基类派生，在派生类中定义函数操作符:\par

\begin{lstlisting}[caption={}]
virtual int operator()(const device &dev) const {
	; /* User logic */
}
\end{lstlisting}

从device\_selector派生的类中定义这个操作符，是定义复杂选择逻辑所必须的，需要了解以下三件事:\par

\begin{enumerate}
	\item 当运行时发现程序可访问的设备(包括主机设备)，函数调用操作符会自动调用。
	\item 操作符每次调用时都返回一个分数，可用设备中得分最高的会是选择器所选择的设备。
	\item 函数操作符返回负整数表示不能选择相应的设备。
\end{enumerate}

\hspace*{\fill} \par %插入空行
\textbf{设备评分机制}

有很多机制为设备来给定一个分数，例如:\par

\begin{enumerate}
	\item 返回特定设备类的正值。
	\item 匹配设备名称和/或设备供应商字符串。
	\item 基于设备或平台查询，可以在代码中指向整数值。
\end{enumerate}

例如，选择Intel Arria族中FPGA设备的一种方式如图2-15所示。\par

\hspace*{\fill} \par %插入空行
图2-15 Intel Arria FPGA设备的自定义选择器
\begin{lstlisting}[caption={}]
class my_selector : public device_selector {
	public:
	int operator()(const device &dev) const override {
		if (
		dev.get_info<info::device::name>().find("Arria")
			!= std::string::npos &&
		dev.get_info<info::device::vendor>().find("Intel")
			!= std::string::npos) {
		  return 1;
		}
	  return -1;
	}
};
\end{lstlisting}

第12章有更多关于设备选择的讨论和例子(图12-2和12-3)，并会更加深入地讨论get\_info。\par



